import torch
import torch.nn as nn
import matplotlib.pyplot as plt
#本节用pytorch实现一个简单的前馈神经网络并实现二分类
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'
#定义输入层大小，隐藏层大小，输出层大小和批量大小。
n_in,n_h,n_out,batch_size=10,5,1,10

#创建虚假数据集
x=torch.randn(batch_size,n_in)
y=torch.tensor([[1.0],[0.0],[0.0],[1.0],[1.0],[1.0],[0.0],[0.0],[1.0],[1.0]])

#创建顺序模型，包含线性层，ReLU激活函和Sigmoid函数
model=nn.Sequential(
    nn.Linear(n_in,n_h),#输入层到隐藏层的线性变换
    nn.ReLU(),#隐藏层的Relu激活函数
    nn.Linear(n_h,n_out),#隐藏层到输出层的线性函数
    nn.Sigmoid()#输出层的sigmoid函数
)

#定义均方差损失函数和随机梯队下降优化器
criterion=torch.nn.MSELoss()
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

#执行梯度下降算法进行模型训练
for epoch in range(50):#迭代50次
    y_pred=model(x)#先前传播，计算预测值
    loss=criterion(y_pred,y)#计算损失
    print('epoch:',epoch,'loss:',loss.item())#打印损失值

    optimizer.zero_grad() #清零梯度
    loss.backward() #反向传播，计算梯度
    optimizer.step()#更新模型参数


#可视化
y_pred_final=model(x).detach().numpy() #最总预测值
y_actual=y.numpy()

plt.figure(figsize=(8,5))
plt.plot(range(1,batch_size+1),y_actual,'o-',label='Actual',color='blue')
plt.plot(range(1,batch_size+1),y_pred_final,'x--',label='Predicted',color='red')
plt.xlabel('Sample Index')
plt.ylabel('Value')
plt.title('Actual vs Predictied Values')
plt.legend()
plt.grid()
plt.show()
